#pragma once
#include <iostream>
#include <memory>
#include "Socket.hpp"
#include "Connection.hpp"
#include "InetAddr.hpp"
#include "Log.hpp"

using namespace socket_ns;

class Listener {

public:
    Listener(int port) 
        : _port(port),
         _listensock(std::make_unique<TcpSocket>())
    {
        _listensock->BuildListenSocket(_port);
    }

    int Sockfd() {
        return _listensock->GetSockfd();
    }

    // 使用listensock接收连接
    void Accepter(Connection* conn) {
        while (true) {
            errno = 0;

            InetAdrr addr;
            int sockfd = _listensock->CreateAccepte(&addr);
            if (sockfd >  0) {
                SetNonBlock(sockfd);
                // 需要将刚获取的连接放入到reactor中
                LOG(INFO, "get a new link, client info: %s\n", addr.AddrString().c_str());
                conn->_R->AddConnection(sockfd, EPOLLIN, addr, NormalConnection);
                // std::cout << "XXXXXX" << std::endl;
            } else {
                // std::cout << "--------" << std::endl;~

                if (errno == EWOULDBLOCK) {
                    LOG(INFO, "get new client over\n");
                    return;
                } else if (errno == EINTR) {
                    continue;
                } else {
                    LOG(ERROR, "get new client error\n");
                    exit(LISTEN_ERROR);
                }
            }
        }
    }

    ~Listener() {
        _listensock->Close();
    }
private:
    int _port;
    std::unique_ptr<Socket> _listensock;
};